Option Explicit On 
Option Strict On

Imports TreeCreeper01Interfaces

'The relationship between nodes and species is hard to explain.
'Only leaf nodes are species, but they could be subclasses of species which would be be hard when constructing the tree.
'I tried a few different ways, but in the end decided this: that species are an optional decoration of the node.

Friend Class cTaxonomicTreeNode

    Implements ITaxonomicTreeNode


    Private mDepthFromRootNode As Integer
    Private mParentNode As ITaxonomicTreeNode
    Private mChildNodeList As List(Of cTaxonomicTreeNode)
    Private mChildNodeIDs As Dictionary(Of String, cTaxonomicTreeNode)
    Private mUniqueKey As String 'This is a built-up compound name 
    Private mName As String 'This is the name of the node itself (final part of the unique key compound name)
    Private mSpecies As cTaxonomicSpecies 'Can be nothing if not a leaf node

    Friend Sub New(ByVal ParentNode As ITaxonomicTreeNode, ByVal UniqueKey As String, ByVal Name As String, ByVal DepthFromRootNode As Integer)

        mParentNode = ParentNode
        mUniqueKey = UniqueKey
        mName = Name
        mChildNodeList = New List(Of cTaxonomicTreeNode)
        mChildNodeIDs = New Dictionary(Of String, cTaxonomicTreeNode)
        mDepthFromRootNode = DepthFromRootNode

    End Sub

    Friend Property Species() As cTaxonomicSpecies
        Get
            Return mSpecies
        End Get
        Set(ByVal value As cTaxonomicSpecies)
            mSpecies = value
        End Set
    End Property

    Friend ReadOnly Property UniqueKey() As String Implements ITaxonomicTreeNode.UniqueKey
        Get
            Return mUniqueKey
        End Get
    End Property

    Friend Function AddChildNode(ByVal UniqueKey As String, ByVal Name As String) As ITaxonomicTreeNode Implements ITaxonomicTreeNode.AddChildNode

        Dim ChildNode As cTaxonomicTreeNode
        Dim ChildDepthFromRootNode As Integer

        ChildDepthFromRootNode = DepthFromRootNode + 1
        ChildNode = New cTaxonomicTreeNode(Me, UniqueKey, Name, ChildDepthFromRootNode)
        mChildNodeList.Add(ChildNode)
        mChildNodeIDs.Add(UniqueKey, ChildNode)

        Return ChildNode

    End Function

    Friend ReadOnly Property ChildNodeCount() As Integer Implements ITaxonomicTreeNode.ChildNodeCount
        Get
            Return mChildNodeList.Count
        End Get
    End Property

    Friend ReadOnly Property ChildNodeItemByIndexBaseOne(ByVal Index As Integer) As ITaxonomicTreeNode Implements ITaxonomicTreeNode.ChildNodeItemByIndexBaseOne
        Get
            Return CType(mChildNodeList.Item(Index - 1), ITaxonomicTreeNode)
        End Get
    End Property

    Friend ReadOnly Property DoesChildExist(ByVal UniqueID As String) As Boolean Implements ITaxonomicTreeNode.DoesChildExist
        Get
            Return (mChildNodeIDs.ContainsKey(UniqueID))
        End Get
    End Property

    Friend ReadOnly Property ChildNodeItemByKey(ByVal UniqueKey As String) As ITaxonomicTreeNode Implements ITaxonomicTreeNode.ChildNodeItemByKey
        Get
            Return mChildNodeIDs.Item(UniqueKey)
        End Get
    End Property

    Friend ReadOnly Property ChildNodes() As List(Of cTaxonomicTreeNode)
        Get
            Return mChildNodeList
        End Get
    End Property

    Friend ReadOnly Property DepthFromRootNode() As Integer Implements ITaxonomicTreeNode.DepthFromRootNode
        Get
            Return mDepthFromRootNode
        End Get
    End Property

    Friend ReadOnly Property ParentNode() As ITaxonomicTreeNode Implements ITaxonomicTreeNode.ParentNode
        Get
            Return mParentNode
        End Get
    End Property

    Friend ReadOnly Property Name() As String Implements ITaxonomicTreeNode.Name
        Get
            Return mName
        End Get
    End Property

End Class
